package com.nimlib.utils;

import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.text.TextUtils;

import com.alibaba.fastjson.JSONObject;
import com.jinlejia.erp.R;
import com.jinlejia.erp.base.ApiConfig;
import com.jinlejia.erp.ui.message.MessageActivity;
import com.jinlejia.erp.utils.SharePTool;
import com.netease.nimlib.sdk.AbortableFuture;
import com.netease.nimlib.sdk.InvocationFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.SDKOptions;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.auth.LoginInfo;
import com.netease.nimlib.sdk.mixpush.MixPushConfig;
import com.netease.nimlib.sdk.mixpush.NIMPushClient;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.CustomNotificationConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.nos.NosService;
import com.netease.nimlib.sdk.nos.model.NosThumbParam;
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.constant.UserInfoFieldEnum;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.netease.nimlib.sdk.uinfo.model.UserInfo;
import com.nimlib.msg.HouseInfoMessage;
import com.nimlib.push.NIMPushMessageHandler;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class NimIMUtils {

    public static final String TEST_ACCOUNT="2016";

    public static final String WANGJIN = NimIMUtils.TEST_ACCOUNT+"a73937256e5c2dfdd9cf8fe674f1";
    public static final String ZouNa = NimIMUtils.TEST_ACCOUNT+"50c9a6e52a963288ccc053d78fdc";

    /**
     * 初始化
     */
    public static void init(Application application){
        SDKOptions options = new SDKOptions();
        options(application,options);
        NimUIKit.init(application);
        NIMClient.init(application,getLoginInfo(application),options);
        NIMPushClient.registerMixPushMessageHandler(NIMPushMessageHandler.getInstance());
        MixPushConfig config = new MixPushConfig();
        NIMPushClient.initPush(config);
    }

    public static NimUserInfo getLocalUser(Context context){
        String pin = SharePTool.getUserInfoBean(context).getPin();
        String account = imAccount(pin);
        return NIMClient.getService(UserService.class).getUserInfo(account);
    }

    static String imAccount(String pin){
        return pin.toLowerCase();
    }

    /**
     * 登录
     * @param context
     * @param pin
     * @param callback
     */
    public static void login(Context context, boolean needToast,String pin, RequestCallback<String> callback){
        StatusCode status = NIMClient.getStatus();
        System.out.println("登录状态："+status.name());
        if (!status.shouldReLogin()){ //如果不需要登录
            LoginInfo account = SP.getUserAccount(context);
            updateUserInfo(context,new NimLoginInfo(account),callback); //更新用户的信息
            return;
        }

        NimIMHttpClient client = new NimIMHttpClient(context);
        RequestCallback<NimLoginInfo> loginCallBack = new RequestCallback<NimLoginInfo>() {
            @Override
            public void onSuccess(NimLoginInfo param) {
                updateUserInfo(context,param,callback); //更新用户的信息
            }

            @Override
            public void onFailed(int code) {
                callback.onFailed(code);
            }

            @Override
            public void onException(Throwable exception) {
                callback.onException(exception);
            }
        };
        client.httpLogin(context,pin,needToast,loginCallBack);
    }

    static void sdkLogin(Context context,String pin, String token, RequestCallback<NimLoginInfo> callback){
        LoginInfo info = new LoginInfo(pin,token);
        AbortableFuture<LoginInfo> login = NIMClient.getService(AuthService.class).
                login(info);
//        noinspection unchecked
        login.setCallback(new RequestCallback<LoginInfo>(){
            @Override
            public void onSuccess(LoginInfo param) {
                NimLoginInfo nimLoginInfo = new NimLoginInfo(param);
                SP.saveUserAccount(context,nimLoginInfo);
                callback.onSuccess(nimLoginInfo);
            }
            @Override
            public void onFailed(int code) {
                callback.onFailed(code);
            }
            @Override
            public void onException(Throwable exception) {
                callback.onException(exception);
            }
        });
    }

    //更新用户的信息
    private static void updateUserInfo(Context context,NimLoginInfo nimLoginInfo,RequestCallback<String> callback){
        SharePTool.UserInfoBean infoBean = SharePTool.getUserInfoBean(context);
        NimLoginInfo userAccount = SP.getUserAccount(context);
        // 当本地存储的一致，则不进行更新
        if (TextUtils.equals(userAccount.getAvatar(),infoBean.getImageUrl()) &&
            TextUtils.equals(userAccount.getName(),infoBean.getUserName()) &&
            TextUtils.equals(userAccount.getMobile(),infoBean.getTelNum())){
            if (callback!=null)
                callback.onSuccess(nimLoginInfo.getAccount());
            return;
        }

        Map<UserInfoFieldEnum, Object> userInfo = new HashMap<>();
        String userAvatar = infoBean.getImageUrl();
        String userName = infoBean.getUserName();
        String userMobile = infoBean.getTelNum();
        userInfo.put(UserInfoFieldEnum.AVATAR, ApiConfig.HEADER_URL().concat(userAvatar));
        userInfo.put(UserInfoFieldEnum.Name,userName);
        userInfo.put(UserInfoFieldEnum.MOBILE,userMobile);
        NIMClient.getService(UserService.class).updateUserInfo(userInfo).setCallback(new RequestCallbackWrapper<Void>() {
            @Override
            public void onResult(int code, Void result, Throwable exception) {
                NimUserInfoCache.getInstance().buildCache();
                //无论更新用户信息成功与否，都直接进行聊天
                if (code==200){
                    userAccount.setAvatar(userAvatar);
                    userAccount.setName(userName);
                    userAccount.setMobile(userMobile);
                    SP.saveUserAccount(context,userAccount);
                }
                if (callback!=null)
                    callback.onSuccess(nimLoginInfo.getAccount());


            }
        });

    }

    private static LoginInfo getLoginInfo(Context context){
        return SP.getUserAccount(context);
    }

    /**
     *
     * @return true:有未读消息 false:没有未读消息
     */
    public static boolean hasUnread(){
        MsgService service = NIMClient.getService(MsgService.class);
        return service.getTotalUnreadCount()!=0;
    }

    private static void options(Context context,SDKOptions options){
        StatusBarNotificationConfig config = new StatusBarNotificationConfig();
        config.notificationEntrance = MessageActivity.class; // 点击通知栏跳转到该Activity
        config.notificationSmallIconId = R.mipmap.jpush_notification_icon;
        // 呼吸灯配置
        config.ledARGB = Color.GREEN;
        config.ledOnMs = 1000;
        config.ledOffMs = 1500;
        options.statusBarNotificationConfig = config;
        options.useXLog = true;
        options.userInfoProvider = new UserInfoProvider() {
            @Override
            public UserInfo getUserInfo(String account) {
                return null;
            }

            @Override
            public String getDisplayNameForMessageNotifier(String account, String sessionId, SessionTypeEnum sessionType) {
                return null;
            }

            @Override
            public Bitmap getAvatarForMessageNotifier(SessionTypeEnum sessionType, String sessionId) {
                try {
                    return Picasso.with(context).load(R.mipmap.jpush_notification_icon).get();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }

            }
        };
    }

    //发送文本消息
    public static void sendTextMessage(String sessionId,String text,SendTextMessageCallBack callBack) {
        final IMMessage msg = MessageBuilder.createTextMessage(sessionId,SessionTypeEnum.P2P,text);
        callBack.onBeforeSendText(msg);
        NIMClient.getService(MsgService.class).updateIMMessageStatus(msg);
        NIMClient.getService(MsgService.class).sendMessage(msg,true).setCallback(new RequestCallbackWrapper<Void>() {
            @Override
            public void onResult(int code, Void result, Throwable exception) {
                if (code==200){
                    callBack.onSendTextSuccess(msg);
                }else {
                    callBack.onSendTextFailed(msg);
                }
            }
        });
    }

    //发送正在输入
    private static long typingTime=0L;
    public static void sendTypingCommand(String sessionId){
        if (System.currentTimeMillis() - typingTime > 5000L){
            typingTime = System.currentTimeMillis();
            CustomNotification command = new CustomNotification();
            command.setSessionId(sessionId);
            command.setSessionType(SessionTypeEnum.P2P);
            CustomNotificationConfig config = new CustomNotificationConfig();
            config.enablePush = false;
            config.enableUnreadCount = false;
            command.setConfig(config);
            JSONObject json = new JSONObject();
            json.put("id", "1");
            command.setContent(json.toString());
            NIMClient.getService(MsgService.class).sendCustomNotification(command);
        }
    }

    public static void sendImageMessage(String sessionId,String filePath,SendImageMessageCallBack callBack){
        File file = new File(filePath);
        MsgService service = NIMClient.getService(MsgService.class);
        IMMessage msg = MessageBuilder.createImageMessage(sessionId,SessionTypeEnum.P2P,file,file.getName());
        callBack.onBeforeSendImage(msg);
        service.sendMessage(msg, true).setCallback(new RequestCallbackWrapper<Void>() {
            @Override
            public void onResult(int code, Void result, Throwable exception) {
                if (code==200){
                    callBack.onSendImageSuccess(msg);
                }else {
                    callBack.onSendImageFailed(msg);
                }
            }
        });
    }

    //发送消息已读回执
    public static void sendMessageRe(String sessionId,IMMessage message){
        NIMClient.getService(MsgService.class).sendMessageReceipt(sessionId,message);
    }

    public static void clearUnreadCount(String account){
        NIMClient.getService(MsgService.class).clearUnreadCount(account,SessionTypeEnum.P2P);
    }

    public static void queryRecentContacts(RequestCallbackWrapper<List<RecentContact>> callbackWrapper){
        NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(
                callbackWrapper);
    }

    public static RecentContact queryRecentContact(String contactId){
        return NIMClient.getService(MsgService.class).queryRecentContact(contactId, SessionTypeEnum.P2P);
    }

    public static void changeUserState(){
        NIMClient.getService(UserService.class).setUserState(1);
    }

    public static void fetchUserInfo(String account,RequestCallbackWrapper<List<NimUserInfo>> callbackWrapper){
        InvocationFuture<List<NimUserInfo>> info = NIMClient.getService(UserService.class).fetchUserInfo(Collections.singletonList(account));
        info.setCallback(new RequestCallbackWrapper<List<NimUserInfo>>() {
            @Override
            public void onResult(int code, List<NimUserInfo> result, Throwable exception) {
                NimUserInfoCache.getInstance().buildCache();
                callbackWrapper.onResult(code,result,exception);
            }
        });
    }

    public static void sendHouseInfo(String sessionId, HouseInfoMessage msg,SendCustomMessageCallBack callBack){
        IMMessage message = MessageBuilder.createCustomMessage(sessionId, SessionTypeEnum.P2P, "[推荐]", msg);
        message.setContent("[房源消息]");
        message.setPushContent("[房源消息]");
        callBack.onBeforeSendCustomMessage(message);
        InvocationFuture<Void> future = NIMClient.getService(MsgService.class).sendMessage(message, true);
        future.setCallback(new RequestCallbackWrapper<Void>() {
            @Override
            public void onResult(int code, Void result, Throwable exception) {
                if (code==200){
                    callBack.onSendCustomMessageSuccess(message);
                }else {
                    callBack.onSendCustomMessageFailed(message);
                }
            }
        });
    }

    public static void allRead(){
        NIMClient.getService(MsgService.class).clearAllUnreadCount();
    }

    public static void downloadImageFile(String url, NosThumbParam thumb,final String path,RequestCallbackWrapper callback){
        NIMClient.getService(NosService.class).download(url,thumb,path).setCallback(callback);
    }

    public static void queryMessage(RequestCallbackWrapper<List<IMMessage>> callbackWrapper,String...uuid){
        NIMClient.getService(MsgService.class).queryMessageListByUuid(Arrays.asList(uuid)).setCallback(callbackWrapper);
    }

    public static void logout(Context context) {
        NIMClient.getService(AuthService.class).logout();
        SP.deleteUserAccount(context);
    }

    public interface SendImageMessageCallBack{
        void onBeforeSendImage(IMMessage message);
        void onSendImageSuccess(IMMessage message);
        void onSendImageFailed(IMMessage message);
    }


    public interface SendCustomMessageCallBack{
        void onBeforeSendCustomMessage(IMMessage message);
        void onSendCustomMessageSuccess(IMMessage message);
        void onSendCustomMessageFailed(IMMessage message);
    }

    public interface SendTextMessageCallBack{
        void onBeforeSendText(IMMessage message);
        void onSendTextSuccess(IMMessage message);
        void onSendTextFailed(IMMessage message);
    }
}
